package client;

import java.io.File;

import networkdescriptor.NetworkDescriptor;
import model.jena.properties.FileItem;
import model.jena.properties.FileStore;
import multicast.MulticastCommsClient;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ResIterator;
import com.hp.hpl.jena.rdf.model.Resource;

import constants.NetworkConstants;

import handlers.ClientStatusHandler;
import handlers.UploadRequestHandler;
import tcp.command.CommandManager;
import tcp.filetransfer.FileTransferClient;
import tcp.filetransfer.FileTransferManager;

public class FileStoreClient implements UploadRequestHandler{
	private boolean isConnected = true ;
	private static int CLIENT_DEFAULT_PORT = 9999;
	private CommandManager cmManager;
	private MulticastCommsClient multiClient ;
	private Model systemModel;
	private String destination;
	private String uploadHost ;
	private int uploadPort ;
	
	public FileStoreClient() {
		this.cmManager = new CommandManager(CLIENT_DEFAULT_PORT);
		this.multiClient = new MulticastCommsClient();
		this.destination = "";
		this.multiClient.sendMessage("CLIENT:"+this.multiClient.getMyAddress().getHostAddress()+":CP|"+9999);
		this.uploadHost = "localhost";
		this.uploadPort = NetworkConstants.DEFAULT_FU_PORT;
		this.cmManager.setUploadRequestHandler(this);
	}
	
	public boolean isConnected() {
		return isConnected;
	}

	public void setConnected(boolean isConnected) {
		this.isConnected = isConnected;
	}
	public void addStatusHandler(ClientStatusHandler handler){
		this.cmManager.setClientStatusHandler(handler);
	}

	public Model getSystemModel() {
		return systemModel;
	}

	public void setSystemModel(Model systemModel) {
		this.systemModel = systemModel;
	}
	public void setDestination(String destination) {
		this.destination = destination;
	}
	public void sendDeleteFileReques(String filename){
		this.multiClient.sendMessage("DELETE:"+filename);
	}
	public boolean donwloadFile(String filename){
		ResIterator iter = this.systemModel.listResourcesWithProperty(FileItem.FILENAME);
		Resource foundFile = null;
		while(iter.hasNext()){
			Resource temp = iter.next();
			if(temp.getProperty(FileItem.FILENAME).getString().equalsIgnoreCase(filename)){
				foundFile = temp;
				break;
			}
		}
		if(foundFile != null){
			NetworkDescriptor nd = new NetworkDescriptor();
			nd.setHostname(foundFile.getProperty(FileItem.PRIMARY_DOWNLOAD_HOSTNAME).getString());
			nd.setPortNumber(foundFile.getProperty(FileItem.PRIMARY_DOWNLOAD_PORT).getInt());
			boolean attemptSuccessful = FileTransferClient.requestFileDownload(nd, filename, destination) ;
			if(!attemptSuccessful){
				//Get from secondary location
				nd.setHostname(foundFile.getProperty(FileItem.SECONDARY_DOWNLOAD_HOSTNAME).getString());
				nd.setPortNumber(foundFile.getProperty(FileItem.SECONDARY_DOWNLOAD_PORT).getInt());
				attemptSuccessful = FileTransferClient.requestFileDownload(nd, filename, destination);
				return attemptSuccessful;
				
			}else{
				return attemptSuccessful;
			}
		}
		return false;
	}
	public void updateFile(String filename, String fileToBeUsedForUpdate){
		File uploadFile = new File(fileToBeUsedForUpdate);
		ResIterator iter = this.systemModel.listResourcesWithProperty(FileItem.FILENAME);
		Resource foundFile = null;
		while(iter.hasNext()){
			Resource temp = iter.next();
			if(temp.getProperty(FileItem.FILENAME).getString().equalsIgnoreCase(filename)){
				foundFile = temp;
				break;
			}
		}

	}
	public void uploadFile(String filename,ProgressUpdater updater){
		multiClient.sendMessage("UPLOAD:"+this.multiClient.getMyAddress().getHostAddress()+":CP|"+9999);
		updater.updateProgress(33);
		File fileToUpload = new File(filename);
		updater.updateProgress(33);
		FileTransferClient.requestFileUpload(this.uploadHost, this.uploadPort, fileToUpload);
		updater.updateProgress(100);
	}
	public void handleUploadResponse(String hostname, int portNumber) {
		this.uploadHost = hostname;
		this.uploadPort = portNumber;
	}
}
